using System;
using System.Collections;

namespace sforceExplorer
{

	public delegate void QueryTiming(System.TimeSpan elapsedTime);

	public class SforceServiceWrapper: sforce.SforceService
	{
		private bool _acceptZippedResponse;
		private bool _sendZippedRequest;
		private bool _logMessages;
		
		public event QueryTiming OnQueryComplete;

		public bool LogMessages
		{
			set { _logMessages = value; }
			get { return _logMessages; }
		}

		public new sforce.DescribeSObjectResult describeSObject(string type) 
		{
			type = type.ToLower();
			if (!DataCache.Cache.ContainsKey(type)) 
			{
				Hashtable desc = new Hashtable();
				sforce.DescribeSObjectResult dsr = base.describeSObject(type);
				desc.Add("describe", dsr);
				//Add the fields for direct access
				Hashtable fields = new Hashtable();
				for (int i=0;i<dsr.fields.Length;i++) 
				{
					fields.Add(dsr.fields[i].name.ToLower(), dsr.fields[i]);
				}
				desc.Add("fields", fields);
				DataCache.Cache.Add(type, desc);
			} 	
			return (sforce.DescribeSObjectResult)((Hashtable)DataCache.Cache[type])["describe"];
		}

		public new sforce.QueryResult query(string queryString) 
		{
			long start = DateTime.Now.Ticks;
			sforce.QueryResult qr = base.query(queryString);
			if (OnQueryComplete != null) 
				OnQueryComplete(new TimeSpan(DateTime.Now.Ticks - start));
			return qr;
		}

		/// <summary>
		/// Property to toggle compression on and off, set to true to enable sending compressed requests, false to disable.
		/// </summary>
		public bool SendZippedRequest
		{
			set { _sendZippedRequest = value;}
			get { return _sendZippedRequest;}
		}
		/// <summary>
		/// Property to toggle compression on and off, set to true to enable receiving compressed responses, false to disable.
		/// </summary>
		public bool AcceptZippedResponse
		{
			set { _acceptZippedResponse = value;}
			get { return _acceptZippedResponse;}
		}

		/// <summary>
		/// This constructor will create a request that has has it's initial compression
		/// attributes set to the parameter values.
		/// </summary>
		/// <param name="acceptZippedResponse">
		/// Set to true to accept a zipped response, false to accept plain response.
		/// </param>
		/// <param name="sendZippedRequest">
		/// Set to true to send a zipped request, false to send plain response.
		/// </param>
		public SforceServiceWrapper(bool acceptZippedResponse, bool sendZippedRequest) 
		{
			_acceptZippedResponse = acceptZippedResponse;
			_sendZippedRequest = sendZippedRequest;
		}

		/// <summary>This constructor will create a request that has compression off by default (can be enabled later).</summary>
		/// <remarks>
		/// You can later set compression instructions using the SendZippedRequest
		/// property and the <para>AcceptZippedResponse property to turn compression on and off.</para></remarks>
		public SforceServiceWrapper() 
		{
			_acceptZippedResponse = false;
			_sendZippedRequest = false;
			_logMessages = false;
		}

		protected override System.Net.WebRequest GetWebRequest(Uri uri)
		{
			// sforce support compression in both directions.
			return new WebRequestWrapper(base.GetWebRequest(uri), SendZippedRequest, AcceptZippedResponse, LogMessages);
		}
	}
}
